#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Mikan Web Application Package

Mikan Python Web Framework
"""

__author__ = "K.Sonohara"
__status__ = "develop"
__version__ = "0.0.0_30"
__date__    = "2013/09/01"
__license__ = 'LGPL'

# ------------------------------------------------------------
## Import Section
# ------------------------------------------------------------
# Ptyhon
import os
import os.path
import logging.config
import traceback

# ESiPC
from esipc import ESiPCProperty
from esipc.resource.iniresource import ESiPCINIFileResourceBundle

# Mikan
from mikan.app import MikanFileViewApp
from mikan.core import AbstractMikan, MIKAN_INI
from mikan.exception import AbstractMikanStatusException, MikanStatusException

# ------------------------------------------------------------
## Variable Section
# ------------------------------------------------------------

# ------------------------------------------------------------
## Function Section
# ------------------------------------------------------------

# ------------------------------------------------------------
## Class Section
# ------------------------------------------------------------

# ------------------------------------------------------------
## Mikan Webアプリケーションクラス
#
class MikanWebapp(AbstractMikan):

	# ----------------------------------------------------
	## リロード フィールドゲッター
	# @return 取得した値
	def set_reload(self, value):
		self.FReload = value

	# ----------------------------------------------------
	## リロード フィールドゲッター
	# @return 取得した値
	def is_reload(self):
		return self.FReload

	# ----------------------------------------------------
	## サイト セッション フィールドゲッター
	# @return 取得した値
	def get_site_session(self):
		try:
			return self.FSiteSession
		except:
			try:
				from mikan.session.memcachesession import MikanMemcacheSiteSession
				self.FSiteSession = MikanMemcacheSiteSession(self)
				return self.FSiteSession
			except:
				pass
		return None

	# ----------------------------------------------------
	## INIファイル フィールドゲッター
	# @return 取得した値
	def get_config(self):
		return self.FConfig

	# ----------------------------------------------------
	## コンストラクタ
	#  @param reloading リロード処理するかどうか
	#  @param mikan_root MIKAN_ROOT
	#  @param mikan_config MIKAN_CONFIG
	def __init__(self, reloading=False, mikan_root=os.path.dirname(__file__) + '/..', mikan_config=os.path.dirname(__file__) + '/../etc'):
		# MikanRoot位置
		self.FReload = reloading

		# MikanRoot位置
		AbstractMikan.fmikanroot = mikan_root
		AbstractMikan.fmikanconfig = mikan_config

		# 設定ファイル名
		config_name = self.mikanconfig + '/mikan.ini'
		log_name = self.mikanconfig + '/log.ini'

		# 設定ファイル読み込み
		self.FConfig = ESiPCINIFileResourceBundle(config_name, osenv=True)

		# ログ設定ファイル名
		logging.config.fileConfig(log_name)
		AbstractMikan.flogger = logging.getLogger(MIKAN_INI.LOG_MIKAN)

		# ログ
		if self.islogdebug:
			self.logger.debug("Mikan Name = %s", self.MIKAN_NAME)
			self.logger.debug("Mikan Version = %s", self.MIKAN_VERSION)
			self.logger.debug("Mikan Root = %s", mikan_root)
			self.logger.debug("Mikan Config = %s", mikan_config)
			self.logger.debug("Mikan Setting = %s", config_name)
			self.logger.debug("Mikan Log Setting = %s", log_name)

		# 継承元処理
		super(MikanWebapp, self).__init__()

	def create_app(self, request):
		# ログ
		if self.islogdebug:
			self.logger.debug(request.pathinfo)
			self.logger.debug(request.realpath)
			self.logger.debug(request.appspath)

		# ファイル表示用設定
		if request.config.get("mikan", "file") == "true":
			# ログ
			if self.islogdebug:
				self.logger.debug(request.htdocsdir)

			# 表示すべきファイル名
			p = request.htdocsdir + request.realpath.replace('/', os.sep)

			# ログ
			if self.islogdebug:
				self.logger.debug(p)

			# 表示すべきファイルがある場合
			if (os.path.isfile(p)):
				# ログ
				if self.islogdebug:
					self.logger.debug(p)

				# ファイル表示アプリケーション
				return MikanFileViewApp(request, p)

		return self.create_app_auto(request)

	def create_app_auto(self, request):
		# ログ
		if self.islogdebug:
			self.logger.debug("apps: %s", "apps" + request.apps)

		# モジュール名作成
		module = "apps" + request.apps
		fromlist = [module]

		# モジュールインポート
		module = __import__(module, fromlist=fromlist)

		# リロード
		if self.isreload:
			reload(module)

		# クラス名取得
		c = getattr(module, request.appname)

		# クラスのインスタンス初期化
		return c(request)

	# ----------------------------------------------------
	## 処理
	#  @param request リクエスト
	def perform(self, request):
		# 処理結果用
		aaa = None

		try:
			aaa = self.create_app(request)
		except:
			# ログ
			self.logger.error(traceback.format_exc())
			# 見つからないエラー
			raise MikanStatusException(request, 404)

		# 対象アプリケーションがある場合
		if (aaa != None):
			# ログ
			if self.islogdebug:
				self.logger.debug(aaa)

			# 事前処理
			if (aaa.prepare()):
				# 処理
				aaa.perform()

			# 処理がOKで無い場合エラー処理
			if(request.status != 200):
				# エラー表示用アプリケーション
				raise MikanStatusException(request, request.status)

		# 処理結果
		return aaa

	# ----------------------------------------------------
	## Property
	isreload = ESiPCProperty(is_reload, set_reload, None)
	sitesession = ESiPCProperty(get_site_session, None, None)
	config = ESiPCProperty(get_config, None, None)

# ------------------------------------------------------------
## Main Section
# ------------------------------------------------------------
## Main
if __name__ == '__main__':
	pass

# ------------------------------------------------------------
